home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Development Tools & Languages / HyperCard Related / APDA HyperCard Toolkits / HyperCard CTB Toolkit 1.0b2 / Source Code / NBPZoneList.p < prev   
Encoding:
Text File  |  1995-02-07  |  4.3 KB  |  144 lines  |  [TEXT/MPS ]

  1. (*
  2.     NBPZoneList() -- Return a list of the zones on the local network.
  3.  
  4.     To compile and link this file using Macintosh Programmer's Workshop,
  5.  
  6.         pascal -w NBPZoneList.p
  7.         link -m ENTRYPOINT -o HyperCommands -rt XFCN=2765 -sn Main=NBPZoneList ∂
  8.             NBPZoneList.p.o "{MPW}"Libraries:interface.o "{MPW}"Libraries:Libraries:HyperXLib.o
  9.  
  10.     © Copyright 1990 by Apple Computer, Inc.
  11.  
  12.     Initial coding 6/90 by Harry R. Chesley.
  13. *)
  14.  
  15. {$R-}
  16.  
  17. {$S NBPZoneList }     { Segment name must be the same as the command name. }
  18.  
  19. unit DummyUnit;
  20.  
  21. interface
  22.  
  23. uses MemTypes, QuickDraw, OSIntf, ToolIntf, CTBUtils, FTIntf, CMIntf, TMIntf, CRMIntf, AppleTalk, HyperXCmd;
  24.  
  25. procedure EntryPoint(paramPtr: XCmdPtr);
  26.     
  27. implementation
  28.  
  29. procedure NBPZoneList(paramPtr: XCmdPtr); forward;
  30.  
  31. procedure EntryPoint(paramPtr: XCmdPtr);
  32.  
  33.     begin
  34.         NBPZoneList(paramPtr);
  35.     end;
  36.  
  37. procedure NBPZoneList(paramPtr: XCmdPtr);
  38.  
  39.     {$I CTBUtil.inc}
  40.  
  41.     const kReturn = 13;
  42.         kATPTimeOutVal = 3;                { Re-try ATP SendRequest every 3 seconds. }
  43.         kATPRetryCount = 5;                { For five times. }
  44.         kZonesSize = 578;                    { Size of buffer for zone names. }
  45.         kGZLCall = $08000000;            { GetZoneList indicator. }
  46.         kZIPSocket = 6;                        { The Zone Information Protocol socket. }
  47.         kMoreZones = $FF000000;        { Mask to see if more zones to come. }
  48.         kZoneCount = $0000FFFF;            { Mask to count zones in buffer. }
  49.  
  50.     var dATPPBptr: ATPPBptr;            { The parameter block for GetZoneList call. }
  51.         dBDS: BDSElement;                    { The BDS for GetZoneList call. }
  52.         dZones, dCurr: Ptr;                    { The data buffer for GetZoneList call. }
  53.         dIndex, dCount, dNode, dNet: INTEGER;
  54.         ignore: INTEGER;
  55.         result: Handle;
  56.         resultSize: longInt;
  57.         p: Ptr;
  58.  
  59.     procedure Fail(errMsg: Str255); { set theResult and quit }
  60.         begin
  61.             { Get rid of any buffer space we allocated along the way. }
  62.             if dATPPBptr <> nil then DisposPtr(Ptr(dATPPBptr));
  63.             if dZones <> nil then DisposPtr(dZones);
  64.             if result <> nil then DisposHandle(result);
  65.             paramPtr^.returnValue := PasToZero(paramPtr,errMsg);
  66.             exit(NBPZoneList);
  67.         end;
  68.             
  69.     begin
  70.         { Init some important variables. }
  71.         dATPPBptr := nil;
  72.         dZones := nil;
  73.         result := nil;
  74.  
  75.         { Check the parameter count. }
  76.         if paramPtr^.paramCount > 0 then Fail('invalid parameter count');
  77.  
  78.         { Open AppleTalk. }
  79.         FailOSErr(OpenDriver('.MPP', ignore));
  80.         { Allocate buffers. }
  81.         dATPPBptr := ATPPBptr(NewPtr(sizeOf(ATPParamBlock)));
  82.         if dATPPBptr = nil then Fail('Out of memory');
  83.         dZones := NewPtr(kZonesSize);
  84.         if dZones = nil then Fail('Out of memory');
  85.         { Fill in the request. }
  86.         with dBDS do
  87.             begin
  88.                 buffSize := kZonesSize;
  89.                 buffPtr := dZones;
  90.             end;
  91.         with dATPPBptr^ do
  92.             begin
  93.                 atpFlags := 0;
  94.                 if GetNodeAddress(ignore, addrBlock.aNet) <> noErr then Fail('');
  95.                 if addrBlock.aNet = 0 then Fail('');
  96.                 addrBlock.aNode := GetBridgeAddress;                { Get node of bridge. }
  97.                 addrBlock.aSocket := kZIPSocket;                        { The socket we want. }
  98.                 reqLength := 0;
  99.                 reqPointer := nil;
  100.                 bdsPointer := @dBDS;
  101.                 numOfBuffs := 1;
  102.                 timeOutVal := kATPTimeOutVal;
  103.                 retryCount := kATPRetryCount;
  104.             end;
  105.         { Prepare to cycle through the answers. }
  106.         dIndex := 1;
  107.         dCount := 0;
  108.         result := NewHandle(0);
  109.         if result = nil then Fail('Out of memory');
  110.         resultSize := 0;
  111.         repeat
  112.             dATPPBptr^.userData := kGZLCall + dIndex;                        { Indicate GetZoneList request. }
  113.             if PSendRequest(dATPPBptr, false) <> noErr then
  114.                 Fail('Network error');
  115.             dCount := dCount + BAnd(dBDS.userBytes, kZoneCount);    { Find out how many returned. }
  116.             dCurr := dZones;                                                                { Put current pointer at start. }
  117.             repeat                                                                                { Get each zone. }
  118.                 resultSize := resultSize + dCurr^ + 1;
  119.                 SetHandleSize(result,resultSize);
  120.                 if MemError <> noErr then Fail('out of memory');
  121.                 BlockMove(pointer(ord4(dCurr)+1),pointer(ord4(result^)+resultSize-dCurr^-1),dCurr^);
  122.                 p := pointer(ord4(result^)+resultSize-1);
  123.                 p^ := kReturn;
  124.                 dCurr := pointer(ord4(dCurr) + dCurr^+1);        { Bump up current pointer. }
  125.                 dIndex := dIndex + 1;                                        { Increment which zone. }
  126.             until dIndex > dCount;
  127.         until (BAnd(dBDS.userBytes, kMoreZones) <> 0);        { Keep going until none left. }
  128.  
  129.         { Get rid of the buffers. }
  130.         DisposPtr(Ptr(dATPPBptr));
  131.         DisposPtr(dZones);
  132.  
  133.         { Terminate and return the result. }
  134.         if resultSize > 0 then
  135.             begin
  136.                 p := pointer(ord4(result^)+resultSize-1);
  137.                 p^ := 0;
  138.                 paramPtr^.returnValue := result;
  139.             end
  140.         else DisposHandle(result);
  141.     end;
  142.  
  143. end.
  144.